import * as A from './actions/content-change'
import F, {clone, set, get} from 'lodash/fp'

let Record = {
    timeline: [],
    canUndo: false,
    canRedo: false,
    index: -1,
}
Record.record = (action, pages) => {
    let snap = []

    switch (action.type) {
        case A.STYLE_CHANGE: {
            let [p, e] = action.path.split('.')

            return { path: `${p}.elements.${e}.css`
                , from: clone(pages[p].elements[e].css)
                , to: clone(action.style)
                }
        }

        case A.CONTENT_CHANGE: {
            let [p, e] = action.path
            , path = `${p}.elements.${e}.content`

            return { path
                , from: get(path, pages)
                , to: action.content
                }
        }

        case A.DELETE_ELM: {
            if (action.path.length !== 1 && path[0]) return false
            let [p, e] = action.path[0].split('.')
            , path = `${p}.elements`

            return { path
                , from: clone(get(path, pages))
                , to: clone(get(path, pages).slice(0, e).concat(get(path, pages).slice(e, Infinity)))
                }
        }
    }

    return false
}

const redo = (from, to) => 
    typeof from === 'string'
        ? to
        : Object.assign({}, from, to)

const undo = (from, to) =>
    typeof from === 'string'
        ? from
        : clone(from)

const updateOperation = () => {
    Record.canUndo = Record.index >= 0

    Record.canRedo = Record.index < (Record.timeline.length - 1)
    
    return Record
}

Record.undo = pages => {
    if (!updateOperation().canUndo) return pages

    let {path, from, to} = Record.timeline[Record.index]
    
    Record.index -= 1
    updateOperation()
    return set(path, undo(from, to), pages)
}

Record.redo = pages => {
    if (!updateOperation().canRedo) return pages

    Record.index += 1
    updateOperation()
    let {path, from, to} = Record.timeline[Record.index]
    return set(path, redo(from, to), pages)
}

const record = (action, pages) => {
    let modif = Record.record(action, pages)

    if (!modif) return Record

    Record.index += 1
    
    Record.timeline.splice(Record.index, Infinity, modif)

    updateOperation()

    return Record
}

export default record